/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stage;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.LinearRing;
import java.io.*;
import java.util.Vector;

/**
 * Classe che contiene i metodi che servono per elaborare il file .jml ed estrarre parte del suo cotenuto
 * @author matteo cuccato
 * @author nicola girardi
 *
 */
public class ElaborazioneFile {

    /**
     * Metodo che cerca all'interno di una stringa le coordinate di un punto
     * @param String s stringa dove cercare le coordinate
     * @return Double[] vettore di double dove vengono salvate le coordinate x e y
     *
     */
    static Double[] trovaCoordinate(String s) {
        int lunghezzas = s.length();
        int pos_prima_cifra = 0;
        int pos_virgola = 0;
        int pos_ultima_cifra = 0;

        for (int i = 0; i < lunghezzas; i++) {
            int a = s.charAt(i);
            //System.out.println(a);
            if (a > 48 && a < 57) {
                //System.out.println(a);
                pos_prima_cifra = i;
                i = lunghezzas;
            }
        }

        for (int i = pos_prima_cifra; i < lunghezzas; i++) {
            if (s.charAt(i) == ',') {
                pos_virgola = i;
            }
        }

        for (int i = pos_virgola + 1; i < lunghezzas; i++) {
            int a = s.charAt(i);
            if ((a < 48 || a > 57) && a != 46) {
                pos_ultima_cifra = i;
                i = lunghezzas;
            }
        }

        Double[] xy = new Double[2];

        String numero = s.substring(pos_prima_cifra, pos_virgola);
        double n = Double.parseDouble(numero);
        xy[0] = n;
        //System.out.println(xy[0]);

        numero = s.substring(pos_virgola + 1, pos_ultima_cifra);
        //System.out.println(numero);
        n = Double.parseDouble(numero);
        xy[1] = n;

        return xy;
    }//end trovaCoordinate

    public static int trovaId(String s, String stringaId) {

        int pos_prima_cifra = 0;
        int pos_ultima_cifra = 0;
        String app = "";
        stringaId = "\"" + stringaId + "\"";

        if (s.indexOf(stringaId) > -1) {
            for (int i = 0; i < s.length(); i++) {
                int a = s.charAt(i);
                if (a > 47 && a < 58) {
                    pos_prima_cifra = i;
                    i = s.length();
                }
            }
            for (int i = pos_prima_cifra + 1; i < s.length(); i++) {
                int a = s.charAt(i);
                if (!(a > 47 && a < 58)) {
                    pos_ultima_cifra = i;
                    i = s.length();
                }
            }
            app = s.substring(pos_prima_cifra, pos_ultima_cifra);
            //System.out.println("stringa app: "+app);

            return Integer.parseInt(app);
        } else {
            return -1;
        }
    }//fine trovaId

    /**
     * Metodo che cerca all'interno di una stringa una sua sottostringa
     * @param String s stringa dove cercare la sottostringa
     * @param String controllo sottostringa da cercare
     * @return boolean restituisce true se la sottostringa e stata trovata, false altrimenti
     *
     */
    static boolean trovaParola(String s, String controllo) {
        int lunghezzas = s.length();
        int pos_minore = 0;
        int pos_maggiore = 0;


        //nome.substring(a,b);
        for (int i = 0; i < lunghezzas; i++) {
            if (s.charAt(i) == '<') {
                pos_minore = i + 1;
            }
            if (s.charAt(i) == '>') {
                pos_maggiore = i;
            }
        }//end for

        String appoggio = s.substring(pos_minore, pos_maggiore);
        //System.out.println(appoggio);

        if (appoggio.equals(controllo)) {
            return true;
        } else {
            return false;
        }
    }//end trovaParola

    /**
     * Metodo che cerca all'interno di un file il tipo di geometria
     * @param String path percorso del file
     * @return String stringa contenente iltipo di geometria
     * @exception IOException
     *
     */
    public static String tipoFigura(String path) {
        String s = "", tipo = "";
        boolean trovato = false;


        try {
            File file = new File(path);
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);

            s = br.readLine();

            while (s != null && !trovato) {

                if (trovaParola(s, "geometry")) {
                    s = br.readLine();
                    int due_punti = s.indexOf(':');
                    tipo = s.substring(due_punti + 1, s.length() - 1);
                    trovato = true;
                }//end if

                s = br.readLine();
            }//end while

            fr.close();
            br.close();
        } catch (IOException e) {
            System.out.println("" + e);
        }

        return tipo;
    }//end tipoFigura

    /**
     * Metodo che partendo da un file crea un oggetto GeometryCollection con dentro tutti gli oggetti contenuti nel file
     * Il metodo torna un oggetto vuoto se non ci sono oggetti, torna null se il path non è specificato.
     * @param String path percorso del file
     * @return GeometryCollection tutti gli oggetti Geometry estratti dal file
     * @exception IOException se il file non esiste
     *
     */
    public static Vector geomArray(String path, String id) {
        if (path.equals("")) {
            return null;
        }

        /*
         * Se troverò oggetti nel file verranno messi qui dentro altrimenti rimarrà vuoto
         */
        try {
            // Apro il file in lettura / creo gli oggetti per leggere
            File file = new File(path);
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);

            // variabili
            Double[] xy = new Double[2];
            boolean appena_uscito = false;
            String s, tipo;
            int t = 0, indice = -1;
            GeometryContainer gc;
            // vector di appoggio che contiene gli oggetti Cordinate
            Vector app = new Vector();
            // vector di appoggio che contiene gli oggetti Geometry
            Vector v = new Vector();

            // Oggetto Coordinate in cui salvo le coordinate prese dal file
            Coordinate c;

            // Oggetto GeometryFactory per la creazione
            GeometryFactory gf = new GeometryFactory();
            Geometry g, g_app;
            Geometry[] g_a = new Geometry[1];

            s = br.readLine();
            // ciclo per lo scorrimento del file
            while (s != null) {

                // cerco e salvo il tipo di geometria
                if (trovaParola(s, "geometry")) {
                    s = br.readLine();
                    int due_punti = s.indexOf(':');
                    tipo = s.substring(due_punti + 1, s.length() - 1);
                    //System.out.println("Tipo di oggetto: "+tipo);

                    if (tipo.equals("Polygon")) {
                        t = 1;
                    } else {
                        t = 2;
                    }
                    //trovato = true;
                }//end if

                appena_uscito = false;
                if (ElaborazioneFile.trovaParola(s, "gml:coordinates")) {

                    while (!(ElaborazioneFile.trovaParola(s, "/gml:coordinates"))) {
                        //System.out.println("" + s);
                        xy = ElaborazioneFile.trovaCoordinate(s);
                        //System.out.println("x: " + xy[0] + " y: " + xy[1]);

                        // istanzio l'oggetto coordinate
                        c = new Coordinate(xy[0], xy[1]);
                        //System.out.println("Sono c: "+c.toString());
                        app.add(c);
                        //System.out.println("Dimensione di app: "+app.size());

                        s = br.readLine();
                    }
                    appena_uscito = true;
                }//end if

                if (appena_uscito) {
                    //System.out.println("s="+s);
                    xy = ElaborazioneFile.trovaCoordinate(s);
                    //System.out.println("x: " + xy[0] + " y: " + xy[1]);

                    c = new Coordinate(xy[0], xy[1]);
                    app.add(c);

                    // entro qui solamente quando ho trovato una struttura

                    // Creo l'array di Coordinate
                    Coordinate[] c_a = new Coordinate[app.size()];

                    // riempio l'array
                    for (int i = 0; i < app.size(); i++) {
                        c_a[i] = (Coordinate) app.elementAt(i);
                    }

                    while( (trovaId(s, id)) < 0 ){
                        s = br.readLine();
                        indice = trovaId(s, id);
                    }

                    // Istanzio l'oggetto Geometry con le coordinate appena estratte
                    // distinguo se è un oggetto di tipo Polygon o LineString
                    switch (t) {
                        case 1:
                            // tipo = Polygon
                            g_app = new GeometryFactory().createLinearRing(c_a);
                            g = new GeometryFactory().createPolygon((LinearRing) g_app, null);

                            gc = new GeometryContainer(indice, g);
                            v.add(gc);
                            break;

                        case 2:
                            // tipo = LineString
                            g = gf.createLineString(c_a);

                            gc = new GeometryContainer(indice, g);
                            v.add(gc);
                            break;
                    }//end switch
                    appena_uscito = false;
                }// fine if appena_sucito

                // Svuoto il vettore per il prossimo oggetto
                app.clear();

                //DA INSERIRE QUI

                s = br.readLine();
            }//end while


            /* Controllo di aver trovato delle geometrie
             * creo un array di oggetti Geometry
             */
//            if (v.size() != 0) {
//                g_a = new Geometry[v.size()];
//                for (int i = 0; i < v.size(); i++) {
//                    g_a[i] = (Geometry) v.get(i);
//                }
//            }//end if controllo su v

            // Creo la GeometryCollection da ritornare
//            GeometryCollection gc = new GeometryFactory().createGeometryCollection(g_a);

            // Chiudo il file usato
            fr.close();
            br.close();

            return v;

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }//end geomArray

    //------------------METODI DI PROVA-----------------------------------------
    static double estrai_primo_numero(String s) {
        int lunghezzas = s.length();
        int pos_maggiore = 0;
        int pos_virgola = 0;

        //nome.substring(a,b);
        for (int i = 0; i < lunghezzas; i++) {
            if (s.charAt(i) == '>') {
                pos_maggiore = i + 1;
            }
            if (s.charAt(i) == ',') {
                pos_virgola = i;
            }
        }//end for

        String numero = s.substring(pos_maggiore, pos_virgola);
        //System.out.println(numero);
        double n = Double.parseDouble(numero);
        return n;
    }//end estrai_numero

    static double estrai_secondo_numero(String s) {
        int lunghezzas = s.length();
        int pos_virgola = 0;

        //nome.substring(a,b);
        for (int i = 0; i < lunghezzas; i++) {
            if (s.charAt(i) == ',') {
                pos_virgola = i + 1;
            }
        }//end for

        String numero = s.substring(pos_virgola, lunghezzas);
        //System.out.println(numero);

        double n = Double.parseDouble(numero);
        return n;
    }//end secondo_numero
    //--------------------------------------------------------------------------
}
